﻿using System;
using System.Windows.Input;

namespace BluEtch.GotPhone.MVVM
{
    public class RelayCommand<T> : ICommand
    {
        /// <summary>
        /// Method to be executed.
        /// </summary>
        private Action<T> _targetExecuteMethod;

        /// <summary>
        /// CanExecute method.
        /// </summary>
        private Func<T, bool> _targetCanExecuteMethod;

        public RelayCommand(Action<T> executeMethod)
        {
            _targetExecuteMethod = executeMethod;
        }

        public RelayCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
        {
            _targetExecuteMethod = executeMethod;
            _targetCanExecuteMethod = canExecuteMethod;
        }

        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }

        #region ICommand Members

        public bool CanExecute(object parameter)
        {
            if (_targetCanExecuteMethod != null)
            {
                T tparm = (T)parameter;

                return _targetCanExecuteMethod(tparm);
            }

            if (_targetExecuteMethod != null)
            {
                return true;
            }

            return false;
        }

        public event EventHandler CanExecuteChanged = delegate { };

        public void Execute(object parameter)
        {
            if (_targetExecuteMethod != null && CanExecute(parameter))
            {
                _targetExecuteMethod((T)parameter);
            }
        }

        #endregion

    }

    public class RelayCommand : ICommand
    {
        /// <summary>
        /// Method to be executed.
        /// </summary>
        private Action _targetExecuteMethod;

        /// <summary>
        /// CanExecute method.
        /// </summary>
        private Func<bool> _targetCanExecuteMethod;

        public RelayCommand(Action executeMethod)
        {
            _targetExecuteMethod = executeMethod;
        }

        public RelayCommand(Action executeMethod, Func<bool> canExecuteMethod)
        {
            _targetExecuteMethod = executeMethod;
            _targetCanExecuteMethod = canExecuteMethod;
        }

        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }

        #region ICommand Members

        public event EventHandler CanExecuteChanged = delegate { };

        public bool CanExecute(object parameter)
        {
            if (_targetCanExecuteMethod != null)
            {
                return _targetCanExecuteMethod();
            }

            if (_targetExecuteMethod != null)
            {
                return true;
            }

            return false;
        }

        public void Execute(object parameter)
        {
            if (_targetExecuteMethod != null && CanExecute(parameter))
            {
                _targetExecuteMethod();
            }
        }

        public void Execute()
        {
            Execute(null);
        }

        #endregion
    }
}
